#ifndef _DECLARE_H_
#define _DECLARE_H_
#include "includes.h"
#include "structs.h"

/* TIMERS */ 
double get_current_time(void);
void init_timers(void);
void start_timer(int);
void reset_timer(int);
void stop_timer(int);
double get_timer(int);
void add_step_time(igraph_vector_ptr_t *, struct step_timer_t *);
struct step_timer_t *make_timer(double,double);
void reset_step_timer(igraph_vector_ptr_t *);
/* TIMERS */ 



/* LOGGER */
void printl_fragments( struct Fragment *fragments, int nfrag);
void printl_msg_buf(struct msg_buf_t *msg);
void printl_msg_buf_all(struct msg_buf_t *msg);
void printl_my_adjlist( my_adjlist_t *al);
void printl_pair(void *ptr);
void printl_edge(struct edge_t *pedge);
void printl_vertex(struct vertex_t *pv);
/* LOGGER */


/* UTILS */
int check_rfile(FILE *rfile, int npart);
void *xmalloc(int size);
void xfree(void **);
void vertex_free(void *ptr);
void print_vertex(FILE *s, struct vertex_t* v);
struct pair_t *my_make_pair(int vid, int dist);
struct edge_t *make_edge(int src, int dst, int attr,int eid);
int va_system(char *fmt,...);
char *va_format(char *fmt,...);
void print_edge(FILE *s, struct edge_t *pedge);
char *getbasename(char *path);
/* UTILS */

/* MESSAGE BUFFER */
void print_msg_buf(FILE *s, struct msg_buf_t *msg);
void print_msg_buf_all(FILE *s, struct msg_buf_t *msg);
void print_pair(FILE *s, void*p);
void clear_in_msg(struct msg_buf_t *msg);
void clear_all_out_msg(struct msg_buf_t *msg);
int sync_message(struct args_t *args, int nfrag);
int add_out_msg_fid(struct msg_buf_t *msg, int fid, void *pp);
igraph_vector_ptr_t *get_out_msg_at(struct msg_buf_t *msg , int index);
int add_in_msg(struct msg_buf_t *msg, void *ptr);
void *get_in_msg_at(struct msg_buf_t *msg, int index);
int get_in_msg_size(struct msg_buf_t *msg);
int get_out_msg_size_at(struct msg_buf_t *msg, int fid);
int msg_buf_init(struct msg_buf_t *msg_buf, int nfrag);
void msg_buf_destroy(struct msg_buf_t *msg);
/*!MESSAGE BUFFER */


/* FRAGMENT */ 
int isInnerVertex(struct Fragment *fragment, struct vertex_t *pv);
int endInnerVertex(struct Fragment *fragment);
struct vertex_t *getInnerVertex(struct Fragment *fragment);
void initInnerVertex(struct Fragment *fragment);
int load_fragment(
                int nfrag,
                igraph_vector_ptr_t *vertices,
                igraph_vector_ptr_t *edges,
                igraph_vector_int_t *fragtable,
                my_adjlist_t *adjlist,
                struct Fragment *fragments);

void fragment_free(struct Fragment *fragment);
void print_fragments(FILE *s, struct Fragment *fragments, int nfrag);
/* !FRAGMENT */

/* MY_ADJLIST */
void my_adjlist_destory(my_adjlist_t *al);
int my_adjlist_init_empty(my_adjlist_t *al, int vn);
igraph_vector_ptr_t *my_adjlist_get(my_adjlist_t *al, int i);
void my_adjlist_print(FILE *s, my_adjlist_t *al);
/*!MY_ADJLIST */

/* CONVERT */

int verfile2gpmetis(char*vfilename , char*efilename, int ncon, char *graphfile);
int dimacs2gpmetis(char *dimacsfile, char *graphfile);
int vfile2vertices(FILE *vfile, int ncon, igraph_vector_ptr_t *vertices);
int call_vfile2vertices(char *filename, int ncon, igraph_vector_ptr_t *vertices);
int call_efile2edges(const char *filename, igraph_vector_ptr_t *edges);
int efile2edges(FILE *efile, igraph_vector_ptr_t *edges);
int vector2igraph_adjlist(int vn, int en, 
                igraph_vector_ptr_t *vertices,
                igraph_vector_ptr_t *edges,
                igraph_adjlist_t *iadjlist);

struct edge_t *swap_and_store(struct edge_t *e);
int vector2my_adjlist(
                igraph_vector_ptr_t *vertices,
                igraph_vector_ptr_t *edges,
                my_adjlist_t *iadjlist);

int my_adjlist2adjlist(
                igraph_vector_ptr_t *vertices,
                my_adjlist_t *al,
                igraph_vector_int_t *xadj,
                igraph_vector_int_t *adjncy,
                igraph_vector_int_t *vwgt,
                igraph_vector_int_t *adjwgt);

int vector2adjlist(int vn, int en, int ncon,
                igraph_vector_ptr_t *vertices,
                igraph_vector_ptr_t *edges,
                idx_t **xadj,
                idx_t **adjncy,
                idx_t **vwgt,
                idx_t **adjwgt);

int vector2adjlistEX(igraph_vector_ptr_t *vertices,
                igraph_vector_ptr_t *edges,
                igraph_vector_int_t *xadj,
                igraph_vector_int_t *adjncy,
                igraph_vector_int_t *vwgt,
                igraph_vector_int_t *adjwgt,
                int ncon);

int call_vector2adjlist(
                int ncon,
                igraph_vector_ptr_t *vertices,
                igraph_vector_ptr_t *edges
                );

int dimacs2files(FILE *dimacs, 
                int npart,
                FILE *vfile, 
                FILE *efile, 
                FILE *rfile);

int my_adjlist2gpmetis(my_adjlist_t *al, int en,
               igraph_vector_ptr_t *vertices, 
               char *fmt,
               FILE *gpmetis);

void adjlist_printf(int vn, int en, int ncon,
                idx_t *xadj, idx_t *adjncy,
                idx_t *vwgt, idx_t *adjwgt);

void print_partition(FILE *stream, idx_t *part, idx_t nvtxs);
int rfile2fragtable(FILE *rfile, 
                int vn, 
                igraph_vector_int_t 
                *fragtable);
/* CONVERT */



/* GRAPE_API */
extern struct grape_graph_t grape_graph;
extern struct grape_var_t grape_var;
extern struct grape_file_t grape_file;
zlog_category_t *grape_inter_logger, *grape_proc_logger;
extern struct grape_data_t grape_data;
extern struct grape_app_t grape_app;
extern struct grape_plugin_t *grape_plugin;
extern struct arguments arguments;

void grape_errexit_if(int cond, int flag, char *fmt, ...);
int grape_get_vn(void);
void grape_load_queries(void);
int grape_get_en(void);
void *grape_get_query(struct args_t *args);
void grape_set_app_name(char *name);
FILE *grape_get_output_file(void);
int grape_fini(void);
int grape_init(struct grape_plugin_t *);
int grape_argp_parse(int,char**,char*,char*);
void grape_load_vertices(void);
void grape_load_edges(void);
void grape_build_global_adjlist(void);
void grape_load_queries(void);
void grape_load_fragments(void);
void grape_load_fragtable(void);

struct Fragment *grape_get_fragment(struct args_t *args);
void *grape_get_partial_result(struct args_t *args);
struct msg_buf_t *grape_get_messages_buffer(struct args_t *args);
int grape_get_fid(struct args_t * args);
int fragment_get_innerv_size(struct Fragment *fragment);
struct vertex_t *fragment_get_innerv_at(struct Fragment *fragment, int vid);
int vertex_get_comm_size(struct vertex_t *pv);
int vertex_get_comm_at(struct vertex_t *pv, int index);
/* GRAPE_API */



/* WORKER */
int is_finish(struct args_t *args, int nfrag); 
int run_on_fragments(void);
void report_run_conf(void);
/* WORKER */

#endif 
/* !_DECLARE_H_ */
